/* * Copyright 2015 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.samples.apps.topeka; import android.support.annotation.NonNull; import android.support.test.InstrumentationRegistry; import android.support.test.espresso.UiController; import android.support.test.espresso.ViewAction; import android.support.test.espresso.matcher.ViewMatchers; import android.text.TextUtils; import android.view.View; import android.widget.AdapterView; import android.widget.GridView; import android.widget.ListView; import android.widget.SeekBar; import com.google.samples.apps.topeka.R; import com.google.samples.apps.topeka.model.quiz.AlphaPickerQuiz; import com.google.samples.apps.topeka.model.quiz.FillBlankQuiz; import com.google.samples.apps.topeka.model.quiz.FillTwoBlanksQuiz; import com.google.samples.apps.topeka.model.quiz.OptionsQuiz; import com.google.samples.apps.topeka.model.quiz.PickerQuiz; import com.google.samples.apps.topeka.model.quiz.Quiz; import com.google.samples.apps.topeka.model.quiz.ToggleTranslateQuiz; import com.google.samples.apps.topeka.model.quiz.TrueFalseQuiz; import org.hamcrest.Matcher; import java.util.Arrays; import java.util.List; import static android.support.test.espresso.Espresso.onData; import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.action.ViewActions.click; import static android.support.test.espresso.action.ViewActions.closeSoftKeyboard; import static android.support.test.espresso.action.ViewActions.typeText; import static android.support.test.espresso.matcher.ViewMatchers.hasSibling; import static android.support.test.espresso.matcher.ViewMatchers.isDescendantOfA; import static android.support.test.espresso.matcher.ViewMatchers.withId; import static android.support.test.espresso.matcher.ViewMatchers.withText; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.instanceOf; /** * Utility for quiz solving. */ public class SolveQuizUtil { /** * Solves a given quiz. * * @param quiz Quiz to solve. */ public static void solveQuiz(Quiz quiz) { switch (quiz.getType()) { case ALPHA_PICKER: setAlphaPickerProgress((AlphaPickerQuiz) quiz); break; case PICKER: setPickerProgress((PickerQuiz) quiz); break; case FILL_BLANK: FillBlankQuiz fillBlankQuiz = (FillBlankQuiz) quiz; String siblingText = fillBlankQuiz.getStart(); if (TextUtils.isEmpty(siblingText)) { siblingText = fillBlankQuiz.getEnd(); } int viewId = R.id.quiz_edit_text; if (TextUtils.isEmpty(siblingText)) { siblingText = quiz.getQuestion(); viewId = R.id.quiz_content; } typeAndCloseOnView(fillBlankQuiz.getAnswer(), siblingText, viewId); break; case FILL_TWO_BLANKS: FillTwoBlanksQuiz fillTwoBlanksQuiz = (FillTwoBlanksQuiz) quiz; typeAndCloseOnView(fillTwoBlanksQuiz.getAnswer()[0], R.id.quiz_edit_text); typeAndCloseOnView(fillTwoBlanksQuiz.getAnswer()[1], R.id.quiz_edit_text_two); break; case FOUR_QUARTER: testOptionsQuizWithType(quiz, GridView.class); break; case SINGLE_SELECT: case SINGLE_SELECT_ITEM: case MULTI_SELECT: testOptionsQuizWithType(quiz, ListView.class); break; case TOGGLE_TRANSLATE: ToggleTranslateQuiz toggleTranslateQuiz = (ToggleTranslateQuiz) quiz; for (int i : toggleTranslateQuiz.getAnswer()) { onData(equalTo(toggleTranslateQuiz.getReadableOptions()[i])) .inAdapterView(allOf(instanceOf(AdapterView.class), withId(R.id.quiz_content), hasSiblingWith(quiz.getQuestion()))) .perform(click()); } break; case TRUE_FALSE: TrueFalseQuiz trueFalseQuiz = (TrueFalseQuiz) quiz; onView(allOf(isDescendantOfA(hasSibling(withText(quiz.getQuestion()))), withText( trueFalseQuiz.getAnswer() ? R.string.btn_true : R.string.btn_false))) .perform(click()); break; } } private static void testOptionsQuizWithType(Quiz quiz, Class<? extends View> type) { @SuppressWarnings("unchecked") OptionsQuiz<String> stringOptionsQuiz = (OptionsQuiz<String>) quiz; for (int i : stringOptionsQuiz.getAnswer()) { onData(equalTo(stringOptionsQuiz.getOptions()[i])) .inAdapterView(allOf(instanceOf(type), withId(R.id.quiz_content), hasSiblingWith(quiz.getQuestion()))) .perform(click()); } } private static void setAlphaPickerProgress(final AlphaPickerQuiz quiz) { onView(allOf(isDescendantOfA(hasSibling(withText(quiz.getQuestion()))), withId(R.id.seekbar))) .perform(new ViewAction() { @Override public Matcher<View> getConstraints() { return ViewMatchers.isAssignableFrom(SeekBar.class); } @Override public String getDescription() { return "Set progress on AlphaPickerQuizView"; } @Override public void perform(UiController uiController, View view) { List<String> alphabet = Arrays.asList(InstrumentationRegistry. getTargetContext() .getResources() .getStringArray(R.array.alphabet)); SeekBar seekBar = (SeekBar) view; seekBar.setProgress(alphabet.indexOf(quiz.getAnswer())); } }); } private static void setPickerProgress(final PickerQuiz pickerQuiz) { onView(allOf(isDescendantOfA(hasSibling(withText(pickerQuiz.getQuestion()))), withId(R.id.seekbar))) .perform(click()) .perform(new ViewAction() { @Override public Matcher<View> getConstraints() { return ViewMatchers.isAssignableFrom(SeekBar.class); } @Override public String getDescription() { return "Set progress on PickerQuizView"; } @Override public void perform(UiController uiController, View view) { SeekBar seekBar = (SeekBar) view; seekBar.setProgress(pickerQuiz.getAnswer()); } }); } private static void typeAndCloseOnView(String answer, String siblingText, int viewId) { onView(allOf(withId(viewId), hasSiblingWith(siblingText))) .perform(typeText(answer), closeSoftKeyboard()); } private static void typeAndCloseOnView(String answer, int viewId) { onView(withId(viewId)) .perform(typeText(answer), closeSoftKeyboard()); } @NonNull private static Matcher<View> hasSiblingWith(String text) { return hasSibling(withText(text)); } }